package cn.wd.user.service.impl;


import cn.wd.common.util.StrUtils;
import cn.wd.model.LoginInfo;
import cn.wd.model.ServiceException;
import cn.wd.user.domain.entity.Employee;
import cn.wd.user.domain.entity.User;
import cn.wd.user.domain.mapper.EmployeeMapper;
import cn.wd.user.domain.mapper.UserMapper;
import cn.wd.user.qo.UserQueryObject;
import cn.wd.user.service.IUserService;
import cn.wd.user.utils.TokenManager;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    private final UserMapper mapper;
    private final EmployeeMapper employeeMapper;
    public UserServiceImpl(UserMapper mapper, EmployeeMapper employeeMapper) {
        this.mapper = mapper;
        this.employeeMapper = employeeMapper;
    }

    @Override
    public User selectUsername(String username) {
        return mapper.selectByUsername(username);
    }

    @Override
    public String login(String username, String password){
        // 1. 基于用户名去数据库查询用户信息
        User user = mapper.selectByUsername(username);

        // 2. 如果信息不存在, 提示用户名或密码错误
        if (user == null) {
            log.error("[用户服务] 登录失败, 用户名输入错误, 提交的用户名={}, 提交的密码={}", username, password);
            throw new RuntimeException("用户名或密码错误");
        }

        // 3. 判断密码是否正确, 如果不正确, 提示用户名或密码错误
        if (!password.equals(user.getPassword())) {
            log.error("[用户服务] 登录失败, 密码输入错误, 提交的用户名={}, 提交的密码={}", username, password);
            throw new RuntimeException("用户名或密码错误");
        }

        // 3.1 判断当前用户状态, 如果状态为禁用(1), 提示该用户处理禁用状态,请申请用户恢复
        if(user.getStatus() == 1){
            log.error("[用户服务] 登录失败, 该用户处于禁用状态, 提交的用户名={}, 提交的密码={}", username, password);
            throw new RuntimeException("该用户处于禁用状态");
        }

        log.info("[用户服务] 用户{}成功登录", username);

        // 4. 生成 token, 并将当前用户存入 map
        String token = TokenManager.getToken();

        LoginInfo loginInfo = new LoginInfo();
        // 将 user 中所有与 loginInfo 对象中属性名相同的属性值全部 copy 到 loginInfo
        BeanUtils.copyProperties(user, loginInfo);

        TokenManager.put(token, loginInfo);

        LoginInfo info = TokenManager.get(token);

        // 5. 返回 token
        return token;
    }

    @Override
    public Page<User> listUserPage(UserQueryObject qo) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<User>();
        if (StrUtils.hasText(qo.getKeyword())) {
            wrapper.or(rap ->
                    rap.like(User::getUsername, qo.getKeyword()).or()
                            .like(User::getNickname, qo.getKeyword())
                            .or().like(User::getSignture, qo.getKeyword()));
        }
        wrapper.eq(qo.getDeleted() != null, User::getDeleted, qo.getDeleted());
        wrapper.eq(qo.getStatus() != null, User::getStatus, qo.getStatus());
        wrapper.ge(qo.getBeginTime() != null, User::getCtime, qo.getBeginTime());
        wrapper.le(qo.getEndTime() != null, User::getCtime, qo.getEndTime());
        return mapper.selectVoPage(qo, wrapper, User.class);
    }


    @Override
    public boolean save(User obj) {
        mapper.insert(obj);
        return true;
    }


    @Override
    public boolean updateById(User obj) {
        mapper.updateByPrimaryKey(obj);
        return true;
    }

    @Override
    public void changeStatus(Long id, Integer status) {
        User user = getById(id);
        if (user.getDeleted()) {
            throw new ServiceException("该用户已删除，不能对其编辑");
        }
        user.setStatus(status);
        saveOrUpdate(user);
    }

    @Override
    public void logicDeleteById(Long id, boolean deleted) {
        update(new LambdaUpdateWrapper<User>().eq(User::getId, id).set(User::getDeleted, deleted));
    }

    /**
     * 重置密码
     * @param token 用户的token，获取用户信息
     * @param newPassword 用户提交的新密码
     * @param oldPassword 用户提交的原始密码
     */
    @Override
    public void restPassword(String token, String newPassword, String oldPassword) {
        LoginInfo loginInfo = TokenManager.get(token);
        Employee employee = employeeMapper.selectByEmployeeName(loginInfo.getUsername());
        if (employee == null) {
            log.error("[用户重置密码业务]： token 中获取不到用户信息");
            throw new RuntimeException("用户名或密码错误！");
        }
        if (! oldPassword.equals(employee.getPassword())) {
            log.error("[用户重置密码业务]： 用户提交的密码和原始密码不符");
            throw new RuntimeException("原始密码错误，请重新再试！");
        }
        employeeMapper.restPassword(loginInfo.getId(), newPassword);
        BeanUtils.copyProperties(employee, loginInfo);
        TokenManager.put(token, loginInfo);
    }

    /**
     * 根据 token 获取用户信息
     * @param token
     * @return
     */
    @Override
    public LoginInfo getLoginInfo(String token) {
        return TokenManager.get(token);
    }
}
